#ifndef GameState_H
#define GameState_H

//#include "astar.h"

#include <OISMouse.h>
#include <OISKeyboard.h>

#include <Ogre.h>

#include "GameManager.h"
#include "GameObject.h"
//#include "InputManager.h"
//#include "AudioManager.h"
//#include "Character.h"
//#include "WorldItem.h"
//#include "UseableItem.h"
//#include "InventoryItem.h"

#include <stdio.h>
#include <stdlib.h>
#include <irrKlang.h>
using namespace irrklang;

class GameState {
public:
	~GameState( void ) { }

	virtual void enter( void )  = 0;
    virtual void exit( void )   = 0;

    virtual void pause( void )  = 0;
    virtual void resume( void ) = 0;
    virtual void update( unsigned long lTimeElapsed ) = 0;
    
    virtual void keyPressed( const OIS::KeyEvent &e )  = 0;
    virtual void keyReleased( const OIS::KeyEvent &e ) = 0;

	//virtual void frameStarted(const Ogre::FrameEvent &evt) = 0;
	//virtual void frameEnded(const Ogre::FrameEvent &evt) = 0;

    virtual void mouseMoved( const OIS::MouseEvent &e ) = 0;
    virtual void mousePressed( const OIS::MouseEvent &e, OIS::MouseButtonID id )  = 0;
    virtual void mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id ) = 0;

    void changeState( GameState *state );
    void pushState( GameState *state );
    void popState( void );
    void requestShutdown( void );

	/*
	void playMusic( const char *source, bool bln ) {
		if( mSoundEngine->isCurrentlyPlaying( source )) {
			mMusic->stop();
		}
		
		mMusic = mSoundEngine->play2D( source, bln, false, true, ESM_AUTO_DETECT, true );
	}

	void stopMusic() {
		mMusic->stop();
	}

	void playSound(const char *source){
		sfx1 = mSoundEngine->play2D( source, false, false, true, ESM_AUTO_DETECT, true );
	}
	*/

	/*
	void addObject( Character* o ) {
		objects.push_back( (GameObject*)o );
		characters.push_back( o );
	}

	void addObject( WorldItem* o ) {
		objects.push_back( (GameObject*)o );
		worlditems.push_back( o );
	}

	void addObject( InventoryItem* o ) {
		objects.push_back( (GameObject*)o );
		inventoryitems.push_back( o );
	}

	void addObject( UseableItem* o ) {
		objects.push_back( (GameObject*)o );
		useableitems.push_back( o );
	}
	*/

	void animate( unsigned long lTimeSinceLastFrame );

	//Going to be in AudioManager.h
	void playSFX( const char *_fileName );
	void playSFX3D( const char *_fileName,  irrklang::vec3df position);
	void playMusic( const char *_fileName, bool bln ); // (music_src, loop)
	void pauseMusic( );
	void resumeMusic( );
	void stopMusic( );
	//void increaseMusicVolume(ik_f32 _step);
	//void decreaseMusicVolume(ik_f32 _step);
	void setAudioVolume( irrklang::ik_f32 _volume );
	irrklang::ik_f32 getAudioVolume();
	void unloadAllSounds( );

	ISoundEngine *mSoundEngine;
	//-------

	Ogre::Root           *mRoot;
    Ogre::Camera         *mCamera;
    Ogre::SceneManager   *mSceneMgr;
    Ogre::Viewport       *mViewport;
    Ogre::OverlayManager *mOverlayMgr;
	//InputManager		*mInputMgr;

	std::vector<GameObject*> objects;
	Ogre::String		mouse_Object_clicked;
	OIS::MouseButtonID	mouse_Button_clicked;
	Ogre::Real			mouse_Coords_X;
	Ogre::Real			mouse_Coords_Y;
protected:
	GameState( void ) { }
private:
	GameState( const GameState& ) { }
	GameState & operator = ( const GameState& );

	// Audio
	irrklang::ik_s32 mInitialSources;
	irrklang::ISound			*mMusic, *sfx1;
};
#endif